bzoj 2190 [SDOI2008]仪仗队

bzoj 2190

显然

以C菌为原点构建坐标系

当横纵坐标(a,b)不互质时,斜率a/b与a/gcd(a,b)和b/gcd(a,b)斜率相等,那么一定会被(a/gcd(a,b),b/gcd(a,b))挡住

那就是求$\sum_{i=1}^{n}\sum_{j=1}^{n} gcd(i,j)=1$

求个欧拉就好了QAQ

线性求欧拉$O(n)$

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
int n;
const int maxn =400004;
int phi[maxn];
void get_phi() {
phi[1]=1;
for(int i=2; i<=n; i++) {
if(!phi[i])
for(int j=i; j<=n; j+=i) {
if(!phi[j])phi[j]=j;
phi[j]=phi[j]/i*(i-1);
}
}
}
int main() {
scanf("%d",&n);
get_phi();
int ans=0;
for(int i=1; i<=n-1; i++)ans+=phi[i];
printf("%d",2*ans+1);
return 0;
}

单个求欧拉

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include<cstdio>
using namespace std;
const int maxn = 1110101;
int oula[maxn];
int prime[maxn];
bool a[maxn];
int n;
int phi(int x) {
int ret=1;
for(int i=2;i*i<=x;i++) {
if(x%i==0) {
ret*=i-1,x/=i;
while(x%i==0) {
ret*=i;x/=i;
}
}
}
if(x>1)ret*=x-1;
return ret;
}
int main () {
scanf("%d",&n);
int ans=0;
for(int i=1;i<n;i++) {
ans+=phi(i);
}
ans=ans*2,ans+=1;
printf("%d\n",ans);
return 0;
}